#pragma once
#include<iostream>
#include<fstream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstdarg>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include"LockGuard.hpp"

bool gisSave = false;
const std::string logname = "log.txt";

enum level
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAl
};

void Sevefile(const std::string &filename,const std::string &message)
{
    std::ofstream out(filename,std::ios::app);
    if(!out.is_open())
    {
        return;
    }
    out<<message;
    out.close();
}

std::string LevelToString(int level)
{
    switch(level)
    {
        case DEBUG:
            return "debug";
        case INFO:
            return "info";
        case WARNING:
            return "warning";
        case FATAl:
            return "fatal";
        default:
            return "unknown";
    }
}

std::string getTimestring()
{
   time_t curr_time = time(nullptr);
   struct tm *foramt = localtime(&curr_time);
   if(foramt==nullptr)
   {
    return "none";
   }
   char time_buffer[1024];
   snprintf(time_buffer,sizeof(time_buffer),"%d-%d-%d %d:%d:%d",
                            foramt->tm_year+1900,
                            foramt->tm_mon+1,
                            foramt->tm_mday,
                            foramt->tm_hour,
                            foramt->tm_min,
                            foramt->tm_sec);
    return time_buffer;
}

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

//日志内容
void logMessage(std::string filename ,int line,bool issave,int level,const char *format,...)
{
    std::string levelstr = LevelToString(level);
    std::string timestr = getTimestring();
    pid_t selfid = getpid();
    char buffer[1024];
    va_list arg;
    va_start(arg,format);
    vsnprintf(buffer,sizeof(buffer),format,arg);
    va_end(arg);
    std::string message = "["+timestr+"]"+"["+levelstr+"]"+"["+std::to_string(selfid)+"]"+"["
    +filename+"]"+"["+std::to_string(line)+"]";
    Lockguard lockguard(&lock);
    if(!issave)
    {
        std::cout<<message;
    }
    else
    {
    Sevefile(logname,message);
    }
}

#define LOG(level, foramt, ...)                                                     \
    do                                                                              \
    {                                                                               \
        logMessage(__FILE__, __LINE__, gisSave, level, foramt, ##__VA_ARGS__); \
    } while (0)
#define EnableFile()    \
    do                  \
    {                   \
        gisSave = true; \
    } while (0)
#define EnableScreen()   \
    do                   \
    {                    \
        gisSave = false; \
    } while (0)
